package com.wushijia.model;

import com.wushijia.java8.lambda.Discount;
import com.wushijia.java8.lambda.Discount.Code;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import lombok.Getter;
import lombok.Setter;

/**
 * description:
 *
 * @author yang
 * @date 2018/6/11 21:39
 */
public class Shop {

  private final Random random = new Random();

  @Setter
  @Getter
  private String name;

  public Shop(String name) {
    this.name = name;
  }

  public String getPrice(String product) {
    double price = calculatePrice(product);
    Discount.Code code = Discount.Code.values()[random.nextInt(Code.values().length)];
    return String.format("%s:%.2f:%s", name, price, code);
  }

  private double calculatePrice(String product) {
    randomDelay();
    return random.nextDouble() * product.charAt(0) + product.charAt(1);
  }

  private void randomDelay() {
    try {
      //随机延迟0.5秒-2.5秒
      long time = 500 + random.nextInt(2000);
      Thread.sleep(time);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public Future<Double> getPriceAsync(String product) {
    CompletableFuture<Double> future = new CompletableFuture<>();
    //在另一个线程中以异步方式执行计算
    new Thread(() -> {
      //需要长时间计算的任务结束并得出结果，设置Future的返回值
      try {
        double price = calculatePrice(product);
        future.complete(price);//结束Future对象的运行，并设置变量的值
      } catch (Exception e) {
        //抛出导致失败的异常，完成这次Future操作
        future.completeExceptionally(e);
      }
    }).start();
    return future;//无需等待计算任务结束，直接返回Future对象
  }

  public Future<Double> getPriceAsyncSimple(String product) {
    //接受一个生产者作为参数，
    return CompletableFuture.supplyAsync(() -> calculatePrice(product));
  }
}
